import sys
import time
from socket import *


class FtpClient:
    def __init__(self, sockfd):
        super().__init__()
        self.sockfd = sockfd

    def do_list(self):
        # 发送请求 L表示请求文件列表
        self.sockfd.send(b'L')
        data = self.sockfd.recv(128).decode()
        # OK表示请求成功
        if data == 'OK':
            # while True:
            #     data = self.sockfd.recv(128)
            #     if data == b'##':
            #         break
            #     print(data.decode())
            # 接收文件列表
            data = self.sockfd.recv(4096)
            print(data.decode())
        else:
            print(data)

    def do_quit(self):
        self.sockfd.send(b'Q')
        self.sockfd.close()
        sys.exit('谢谢使用')

    def do_get(self, filename):
        # 发送请求
        self.sockfd.send(('G ' + filename).encode())
        # 等待回复
        data = self.sockfd.recv(128).decode()
        if data == 'OK':
            fd = open(filename, 'wb')
            # 接收内容写入文件
            while True:
                data = self.sockfd.recv(1024)
                if data == b'##':
                    break
                fd.write(data)
            fd.close()
        else:
            print(data)

    def do_put(self, filename):
        # 发送请求
        print("上传文件", filename)
        self.sockfd.send(('P ' + filename.split('/')[-1]).encode())
        # 等待回复
        data = self.sockfd.recv(128).decode()
        if data == 'OK':
            try:
                fd = open(filename, mode='rb')
            except Exception as e:
                print(e)
                print('文件读取失败')
            else:
                while True:
                    data = fd.read(1024)
                    if not data:
                        # 防止粘包
                        time.sleep(0.1)
                        self.sockfd.send(b'##')
                        break
                    self.sockfd.send(data)
                print('传输成功!')
                fd.close()
        else:
            print(data)


# 发起请求
def request(sockfd):
    ftp = FtpClient(sockfd)
    while True:
        print("""
            ***********命令选项**************
            *********** list **************
            *********** get file **************
            *********** put file **************
            *********** quit **************
        """)

        cmd = input('输入命令：')
        if cmd.strip() == 'list':
            ftp.do_list()
        elif cmd.strip() == 'quit':
            ftp.do_quit()
        elif cmd[:3] == 'get':
            filename = cmd.strip().split(' ')[-1]
            ftp.do_get(filename)
        elif cmd[:3] == 'put':
            filename = ' '.join(list(cmd.strip().split(' ')[1:]))
            ftp.do_put(filename)


# 网络连接
def main():
    # 服务器地址
    ADDR = ('127.0.0.1', 8080)
    sockfd = socket()
    try:
        sockfd.connect(ADDR)
    except Exception as e:
        print('链接服务器失败')
    else:
        print("""*******************
                    Data File Image
                 *******************
        """)
        cls = input('请选择文件种类：')
        if cls not in ['Data', 'File', 'Image']:
            print('Sorry input Error!!')
            return
        else:
            sockfd.send(cls.encode())
            request(sockfd)


if __name__ == "__main__":
    main()
